﻿using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace RuoYi.Framework.Authentication.JwtBearer;

public class JwtBearerTokenHelper
{
    /// <summary>
    /// 生成Token
    /// </summary>
    /// <param name="jwtSettings"></param>
    /// <param name="claims"></param>
    /// <returns></returns>
    public static string GenerateToken(JwtBearerOptions jwtSettings, IEnumerable<Claim> claims)
    {
        // 1. 选择加密算法
        var algorithm = SecurityAlgorithms.HmacSha256;

        // 2. 定义需要使用到的Claims
        //var claims = new[]
        //{
        //    //sub user Id
        //    new Claim(JwtRegisteredClaimNames.Sub, "Duke"),
        //    //role Admin
        //    new Claim(ClaimTypes.Role, "Admin"),
        //};

        // 3. 从 appsettings.json 中读取SecretKey
        var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey));

        // 4. 生成Credentials
        var signingCredentials = new SigningCredentials(secretKey, algorithm);

        // 5. 根据以上组件，生成token
        var notBefore = DateTime.Now;
        var expires = notBefore.AddMinutes(jwtSettings.TokenExpirationMinutes);
        var token = new JwtSecurityToken(
            jwtSettings.Issuer,    //Issuer
            jwtSettings.Audience,  //Audience
            claims,                //Claims,
            notBefore,             //notBefore
            expires,               //expires
            signingCredentials     //signingCredentials
        );

        // 6. 将token变为string
        var jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
        return jwtToken;
    }

    /// <summary>
    /// 校验Token
    /// </summary>
    /// <param name="jwtSettings"></param>
    /// <param name="token"></param>
    /// <returns></returns>
    public static ClaimsPrincipal ValidateToken(JwtBearerOptions jwtBearerOptions, string token)
    { 
        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = jwtBearerOptions.ValidateIssuer,
            ValidateAudience = jwtBearerOptions.ValidateAudience,
            ValidateLifetime = jwtBearerOptions.ValidateLifetime,
            ValidateIssuerSigningKey = jwtBearerOptions.ValidateIssuerSigningKey,
            ValidIssuer = jwtBearerOptions.Issuer,
            ValidAudience = jwtBearerOptions.Audience,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtBearerOptions.SecretKey))
        };

        var claimsPrincipal = new JwtSecurityTokenHandler().ValidateToken(token, tokenValidationParameters, out SecurityToken jwtToken);
        //var jwtPayload = ((JwtSecurityToken)jwtToken).Payload.SerializeToJson();
        //var principalUser = JsonConvert.DeserializeObject<PrincipalUser>(jwtPayload);
        return claimsPrincipal;
    }

    /// <summary>
    /// 直接读取 Token，不含验证
    /// </summary>
    /// <param name="accessToken"></param>
    /// <returns></returns>
    public static JwtSecurityToken ReadJwtToken(string accessToken)
    {
        var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
        var jwtSecurityToken = jwtSecurityTokenHandler.ReadJwtToken(accessToken);
        return jwtSecurityToken;
    }
}
